# -*- coding: utf-8 -*-
# -----------------------
# @Time ： 2021/6/23 3:44 下午
# @Author ： liyi03
# @File ：driver.py
# @IDE ：PyCharm
# -----------------------
import os
import time

import allure
import wda
from loguru import logger

from public.configer import SLEEP, BLACK_LIST, home_page_nine_grid_swipe_path
from public.keyWordAction import KeyWord
from public.time_stamp import time_stamp
from public.wdaClient import wda_client
from utils.handleYaml import YamlHandler


class Driver:
    d = wda_client
    _error_num = 0  # 元素巡检次数初始值,逻辑上允许重新寻找元素三次
    _case_data = None  # yaml 读取的数据

    @classmethod
    def set_case_data(cls, data):
        if not cls._case_data:
            cls._case_data = data

    def action(self, element_data: dict):
        '''
        执行app相关动作
        :param element_data:用例参数
        :return:
        '''
        if isinstance(element_data.get(list(element_data.keys())[0]), str):
            time.sleep(SLEEP)
            msg = "开始执行{}".format(element_data)
            logger.info(msg)
            allure.attach(msg, '执行日志记录', allure.attachment_type.TEXT)
            return self.__sure_action(element_data)
        elif isinstance(element_data.get(list(element_data.keys())[0]), dict):
            self.set_case_data(element_data)
            for step in element_data:
                time.sleep(SLEEP)
                msg = "开始执行{}".format(element_data.get(step))
                logger.info(msg)
                allure.attach(msg, '执行日志记录', allure.attachment_type.TEXT)
                if step == list(element_data.keys())[-1]:
                    # 最后断言或者判断才return
                    return self.__sure_action(element_data.get(step))
                else:
                    self.__sure_action(element_data.get(step))
                    time.sleep(SLEEP)

    def __sure_action(self, element_data):
        '''
        :return:
        '''
        if 'value' in element_data:
            element_ = KeyWord().value(element_data.get("value"))
            return self.__element_action(element_data, element_, 'value_')

        if 'lable' in element_data:
            element_ = KeyWord().lable(element_data.get("lable"))
            return self.__element_action(element_data, element_, 'lable_')

        if 'name' in element_data:
            element_ = KeyWord().name(element_data.get("name"))
            return self.__element_action(element_data, element_, 'name_')

        if 'id' in element_data:
            element_ = KeyWord().id(element_data.get("id"))
            return self.__element_action(element_data, element_, 'id_')

        if 'xpath' in element_data:
            element_ = KeyWord().xpath(element_data.get("xpath"))
            return self.__element_action(element_data, element_, 'xpath_')

    def __element_action(self, element_data, element_, find_element_type):
        '''
        元素执行动作
        :param element_data:
        :param element_:元素连接对象
        :param find_element_type:对应的元素类型
        :return:
        '''

        base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))).replace("\\", '/')
        img = os.path.join(base_path, 'img').replace("\\", "/")
        file_name = "{}/img/{}.png".format(base_path,
                                           time_stamp())  # wda api建议用png后缀截图 https://github.com/openatx/facebook-wda
        try:
            element_execute_action = element_data.get("action")[0]
            if element_execute_action == "click":
                element_.click_(find_element_type)
            if element_execute_action == "send":
                data = element_data.get("action")[-1]
                element_.send_(find_element_type, str(data))
            if element_execute_action == "element":
                return element_.get_text(find_element_type)
            if element_execute_action == "exists":
                return element_.exists_(find_element_type)

        except Exception as e:
            self.d.screenshot(file_name)
            self.__screenshot_report(file_name, img)
            logger.error("操作失败原因%s" % e)
            if self._error_num < 3:
                self._error_num += 1
                msg = f"设备重新寻找元素第【{self._error_num}】次"
                logger.info(msg)
                allure.attach(msg, '定位元素重新寻找记录', allure.attachment_type.TEXT)
                return self.__element_action(element_data, element_, find_element_type)
            if self._error_num == 3 and self._case_data.keys() > 1:
                key_data: str = list(element_data.keys())[0]  # 当前步骤失败key的值
                all_key: list = list(self._case_data.keys())
                retry_excute = self._case_data[all_key[all_key.index(key_data) - 1]]
                msg = f"设备重新执行上一步操作{retry_excute}"
                logger.info(msg)
                allure.attach(msg, '重新执行上步操作记录', allure.attachment_type.TEXT)
                return self.__sure_action(retry_excute)

    def __screenshot_report(self, file_name, img):
        if not os.path.exists(img): os.mkdir(img)
        with open(file_name, mode='rb') as f:
            file = f.read()
            allure.attach(file, "操作截图", allure.attachment_type.PNG)
        logger.info("页面截图文件保存在：{}".format(file_name))

    def send_keys_mum(self, data: str):
        for num in data:
            KeyWord().xpath(f'//*[@label={num}]').click_('xpath_')

    @classmethod
    def black_list_alert_monitor(cls):
        '''
        ios 系统级别弹窗处理
        :return:根据wda的api进行封装未测试
        '''
        print('自动处理的名单', BLACK_LIST)
        with cls.d.alert.watch_and_click(BLACK_LIST):
            cls.d(label="Settings").click()

    @classmethod
    def black_list_alert(cls):
        """
        ios设备app内的弹窗
        :return:根据wda的api进行封装未测试
        """
        list_index = 0
        for retry in BLACK_LIST:
            try:
                cls.d.alert.click(BLACK_LIST)
            except:
                if list_index < len(BLACK_LIST) - 1:
                    list_index += 1
                    cls.d.alert.click(BLACK_LIST[list_index:])

    def input_key(self, mobile_key: str):
        """
        模拟ios手机物理按键
        :param mobile_key: eg：ios的手机按键"home"
        :return:
        """
        self.d.press(mobile_key)

    def home_page_nine_grid_swipe(self, swipe_start: str = None, swipe_end: str = None):
        """
        首页九宫格滑动
        :return:
        """
        # if swipe_start is None and swipe_end is None:
        #     swipe_start, swipe_end = "我的订单", "药房"
        # try:
        #     x1, y1, w1, h1 = KeyWord().value("我的订单").value_.bounds
        #     x2, y2, w2, h2 = KeyWord().value("药房").value_.bounds
        # except Exception as e:
        #     logger.error(e)
        #     return
        # self.d.swipe(x1, y1, x2, y2)


        # x1, y1, y1, y2 = 301, 603, 17, 603  # 我的订单的横纵坐标，药房的横纵坐标
        # x1_percentage, y1_percentage, x2_percentage, y2_percentage = 301/414, 603/896, 17/414, 603/896
        # x1, y1, x2, y2 = x1_percentage*size[0], y1_percentage*size[1], x2_percentage*size[0], y2_percentage*size[1]
        data = YamlHandler(home_page_nine_grid_swipe_path).get_yaml_data()
        self.d.swipe(data["x1"],data["y1"],data["x2"],data["y2"])

    def back_key(self):
        try:
            element_execute_obj = KeyWord().name("hybrid navi back").name_
            _ = (self.d.swipe_right(), element_execute_obj.click())[element_execute_obj.exists]
        except wda.exceptions.WDAElementNotFoundError:
            pass



if __name__ == '__main__':
    Driver().back_key()
